﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using System.Runtime.InteropServices;//为   [DllImport("kernel32.dll")] [DllImport("hfrdapi.dll")]写法提供支持
namespace Super15693
{
    public partial class Form2 : Form
    {
       
        string allblockData = null;//直接读出A卡
        string straread = null;//中间64个解密
        string strbwrite = null;//中间64个加密
        public Form1 Sup = new Form1();//飘逸的一句话 这里面有了整个FORM1的方法
                                       ///-----------句柄------------///
        IntPtr g_hDevice = (IntPtr)(-1); //g_hDevice must init as -1
        ///-----------系统------------///
        [DllImport("kernel32.dll")]
        static extern void Sleep(int dwMilliseconds);

        [DllImport("hfrdapi.dll")]
        static extern int Sys_Open(ref IntPtr device,
                            UInt32 index,
                            UInt16 vid,
                            UInt16 pid);

        [DllImport("hfrdapi.dll")]
        static extern bool Sys_IsOpen(IntPtr device);

        [DllImport("hfrdapi.dll")]
        static extern int Sys_Close(ref IntPtr device);

        [DllImport("hfrdapi.dll")]
        static extern int Sys_SetBuzzer(IntPtr device, byte msec);

        [DllImport("hfrdapi.dll")]
        static extern int Sys_SetAntenna(IntPtr device, byte mode);

        [DllImport("hfrdapi.dll")]
        static extern int Sys_InitType(IntPtr device, byte type);
        //========================= ISO15693 Card Function =========================
        [DllImport("hfrdapi.dll")]
        static extern int I15693_Inventory(IntPtr device, byte[] pData, ref byte pLen);

        [DllImport("hfrdapi.dll")]
        static extern int I15693_Inventorys(IntPtr device, byte[] pData, ref byte pLen);

        [DllImport("hfrdapi.dll")]
        static extern int I15693_GetSystemInformation(IntPtr device,
                                                      byte mode,
                                                      byte[] pUID,
                                                      byte[] pData,
                                                      ref byte pLen);

        [DllImport("hfrdapi.dll")]
        static extern int I15693_Select(IntPtr device, byte[] pUID);

        [DllImport("hfrdapi.dll")]
        static extern int I15693_ResetToReady(IntPtr device, byte mode, byte[] pUID);

        [DllImport("hfrdapi.dll")]
        static extern int I15693_StayQuiet(IntPtr device, byte[] pUID);

        [DllImport("hfrdapi.dll")]
        static extern int I15693_GetBlockSecurity(IntPtr device,
                                                  byte mode,
                                                  byte[] pUID,
                                                  byte block,
                                                  byte number,
                                                  byte[] pData,
                                                  ref byte pLen);

        [DllImport("hfrdapi.dll")]
        static extern int I15693_Read(IntPtr device,
                                      byte mode,
                                      byte[] pUID,
                                      byte block,
                                      byte number,
                                      byte[] pData,
                                      ref byte pLen);

        [DllImport("hfrdapi.dll")]
        static extern int I15693_Write(IntPtr device,
                                       byte mode,
                                       byte[] pUID,
                                       byte block,
                                       byte[] pData);

        [DllImport("hfrdapi.dll")]
        static extern int I15693_LockBlock(IntPtr device,
                                           byte mode,
                                           byte[] pUID,
                                           byte block);

        [DllImport("hfrdapi.dll")]
        static extern int I15693_WriteAFI(IntPtr device,
                                          byte mode,
                                          byte[] pUID,
                                          byte AFI);

        [DllImport("hfrdapi.dll")]
        static extern int I15693_LockAFI(IntPtr device, byte mode, byte[] pUID);

        [DllImport("hfrdapi.dll")]
        static extern int I15693_WriteDSFID(IntPtr device,
                                            byte mode,
                                            byte[] pUID,
                                            byte DSFID);

        [DllImport("hfrdapi.dll")]
        static extern int I15693_LockDSFID(IntPtr device, byte mode, byte[] pUID);

        [DllImport("hfrdapi.dll")]
        static extern int I15693_DirectTransmit(IntPtr device,
                                                byte[] pCommand,
                                                byte cmdLen,
                                                byte[] pData,
                                                ref byte pMsgLg);


        //-------------------------AES128---------------//
        [DllImport("AES128.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)]
        public unsafe static extern void AES_Encode(byte[] inData, byte[] key, byte[] outData);

        [DllImport("AES128.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)]
        public unsafe static extern void AES_Discode(byte[] inData, byte[] key, byte[] outData);


        [DllImport("CRC16.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)]
        public unsafe static extern void creat_CRC(byte[] buf);

        public Form2()
        {
            InitializeComponent();
        }

        //读出A卡内容  & 解密 A卡内容
        private void button1_Click(object sender, EventArgs e)
        {
            int status;
            string UID;
            byte[] UIDdataBuffer = new byte[16];
            byte len = 0;
            byte i = 0;
            //准备
            status = Sys_Open(ref g_hDevice, 0, 0x0416, 0x8020);
            if (true != Sys_IsOpen(g_hDevice)){ MessageBox.Show("The device has not been opened yet !", "error", MessageBoxButtons.OK, MessageBoxIcon.Error); return; }

            //读UID
            status = I15693_Inventory(g_hDevice, UIDdataBuffer, ref len); 
			if (status != 0) {MessageBox.Show("I15693_Inventory failed !", "error", MessageBoxButtons.OK, MessageBoxIcon.Error); return; }
            byte[] bytesData = new byte[64];
            for (i = 0; i < 8; i++)
                bytesData[i] = Marshal.ReadByte(UIDdataBuffer, i + 1);
            UID =Form1.ToHexString(bytesData, 8);
            textBox1.Text = UID;

            //读数据
            byte block = 0;
            byte[] blockData = new byte[64];
            string oneblockData = null;
            for (block = 0; block < 28; block++)//一共28个数据块 全部读出
            {
                // status = I15693_GetBlockSecurity(g_hDevice, 0x02, Form1.ToDigitsBytes(textBox1.Text), block, 1, blockData, ref len);
                status = I15693_Read(g_hDevice, 0x02, Form1.ToDigitsBytes(textBox1.Text), block, 1, blockData, ref len);
                if (status != 0)
                {
                    MessageBox.Show("I15693_GetBlockSecurity failed !", "error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }

                for (i = 0; i < len; i++)
                    blockData[i] = Marshal.ReadByte(blockData, i);
                oneblockData = Form1.ToHexString(blockData, len);
                allblockData += oneblockData;
            }

             richTextBox1.Text = allblockData;//完成任务啦allblockData
             richTextBox1.Text += "#";
             richTextBox1.Text += allblockData.Length.ToString();//是224 其实我hex是4*28=112个
             richTextBox1.Text += "\n";

            //解密数据 
            //准备KEY 8字节的UID就是key 准备8个不一样的KEY
            byte[,] bytekey = new byte[8,8];//8个不一样的key

            //byte[] byteuid = Form1.ToDigitsBytes("71375912942102E0");//伪装阿姨的UID----------------------------------
            //allblockData = "E14020010361D1015D5402656ED8BC2ADD2C87E1A36591678CEC19118DFAB40BF403B92D1629FF5E74341E8695B744326F1B3B51CB55CDCA7C9346FCE5A515E525C69DC6CA205BBC13FB7D98ED0000000000000000001100000000000000930000000000227800000000000000000361";//伪装阿姨的msg

            byte[] byteuid = Form1.ToDigitsBytes(textBox1.Text);
            for (i = 0; i < 8; i++) bytekey[0,i] = byteuid[i];
            for (i = 0; i < 8; i++) bytekey[1,i] = byteuid[7 - i];
            for (i = 0; i < 7; i++) bytekey[2,i] = byteuid[i + 1]; bytekey[2,7] = byteuid[0];
            for (i = 0; i < 6; i++) bytekey[3,i] = byteuid[i + 2]; for (i = 0; i < 2; i++) bytekey[3,6 + i] = byteuid[i];
            for (i = 0; i < 5; i++) bytekey[4,i] = byteuid[i + 3]; for (i = 0; i < 3; i++) bytekey[4,5 + i] = byteuid[i];
            for (i = 0; i < 4; i++) bytekey[5,i] = byteuid[i + 4]; for (i = 0; i < 4; i++) bytekey[5,4 + i] = byteuid[i];
            for (i = 0; i < 3; i++) bytekey[6,i] = byteuid[i + 5]; for (i = 0; i < 5; i++) bytekey[6,3 + i] = byteuid[i];
            for (i = 0; i < 2; i++) bytekey[7,i] = byteuid[i + 6]; for (i = 0; i < 6; i++) bytekey[7,2 + i] = byteuid[i];
            //准备明文
            string strAinput_one = null;
            byte[] byteAinput_one = new byte[8];
            byte[] byteAoutput_one = new byte[8];
            byte[] byteAoutput_all = new byte[8*8];
            byte[] keykey = new byte[8];//二位数组不会 暂时这样吧
            for (i = 0; i < 8; i++)
            {
                //13+8*2*0-------13+8*2*1
                //13+8*2*1-------13+8*2*2
                strAinput_one = allblockData.Substring(13*2+8*2*i , 8*2);//从13*2开始 往后8*2个
                byteAinput_one = Form1.ToDigitsBytes(strAinput_one);
                for (int j = 0; j < 8; j++)
                    keykey[j] = bytekey[i, j];
                unsafe
                {
                    AES_Discode(byteAinput_one, keykey, byteAoutput_one);
                }
                for(int j=0;j<8;j++)
                    byteAoutput_all[8*i+j] = byteAoutput_one[j];//明文好了
            }

            straread = allblockData.Substring(0, 13*2);
            straread += Form1.ToHexString(byteAoutput_all);
            straread += allblockData.Substring(13*2+64*2, 28*4*2 - 13 * 2 - 64 * 2);

            richTextBox1.Text += straread;//读出卡内容解密以后----2straread
            richTextBox1.Text += "\n";
            //成功
            Sys_SetBuzzer(g_hDevice, 20);
        }
        //写B卡
        private void button2_Click(object sender, EventArgs e)
        {
            int status,i;
            string UID;
            byte[] dataBuffer = new byte[64];
            byte len = 0;

            status = Sys_Open(ref g_hDevice, 0, 0x0416, 0x8020);//加一句话吧
            if (true != Sys_IsOpen(g_hDevice)){MessageBox.Show("The device has not been opened yet !", "error", MessageBoxButtons.OK, MessageBoxIcon.Error);return;}

            status = I15693_Inventory(g_hDevice, dataBuffer, ref len);
            if (status != 0){MessageBox.Show("I15693_Inventory failed !", "error", MessageBoxButtons.OK, MessageBoxIcon.Error); return; }
            //读卡B UID
            byte[] bytesData = new byte[64];
            for (i = 0; i < 8; i++)
                bytesData[i] = Marshal.ReadByte(dataBuffer, i + 1);
            UID = Form1.ToHexString(bytesData, 8);
            textBox2.Text = UID;

            //加密
            //准备KEY 8字节的UID就是key
            byte[,] bytekey = new byte[8, 8];//8个不一样的key
            byte[] byteuid = Form1.ToDigitsBytes(textBox2.Text);
            for (i = 0; i < 8; i++) bytekey[0, i] = byteuid[i];
            for (i = 0; i < 8; i++) bytekey[1, i] = byteuid[7 - i];
            for (i = 0; i < 7; i++) bytekey[2, i] = byteuid[i + 1]; bytekey[2, 7] = byteuid[0];
            for (i = 0; i < 6; i++) bytekey[3, i] = byteuid[i + 2]; for (i = 0; i < 2; i++) bytekey[3, 6 + i] = byteuid[i];
            for (i = 0; i < 5; i++) bytekey[4, i] = byteuid[i + 3]; for (i = 0; i < 3; i++) bytekey[4, 5 + i] = byteuid[i];
            for (i = 0; i < 4; i++) bytekey[5, i] = byteuid[i + 4]; for (i = 0; i < 4; i++) bytekey[5, 4 + i] = byteuid[i];
            for (i = 0; i < 3; i++) bytekey[6, i] = byteuid[i + 5]; for (i = 0; i < 5; i++) bytekey[6, 3 + i] = byteuid[i];
            for (i = 0; i < 2; i++) bytekey[7, i] = byteuid[i + 6]; for (i = 0; i < 6; i++) bytekey[7, 2 + i] = byteuid[i];


            string strinput_one = null;//
            byte[] byteinput_one = new byte[8];//
            byte[] byteoutput_one = new byte[8];//
            byte[] byteoutput_all = new byte[8 * 8];
            byte[] keykey = new byte[8];//二位数组不会 暂时这样吧
            for (i = 0; i < 8; i++)
            {
                //13+8*2*0-------13+8*2*1
                //13+8*2*1-------13+8*2*2
                strinput_one = straread.Substring(2*13+8*2*i,  8*2);
                byteinput_one = Form1.ToDigitsBytes(strinput_one);
                for (int j = 0; j < 8; j++)
                    keykey[j] = bytekey[i, j];
                unsafe
                {
                    AES_Encode(byteinput_one, keykey, byteoutput_one);
                }
                for (int j = 0; j < 8; j++)
                    byteoutput_all[8 * i + j] = byteoutput_one[j];//密文好了
            }
            int length = straread.Length;
            strbwrite = straread.Substring(0, 13*2);
            strbwrite += Form1.ToHexString(byteoutput_all);
            strbwrite += straread.Substring(13*2 + 64*2, 28 * 4*2- 13 * 2 - 64 * 2);

            richTextBox1.Text += strbwrite;//读出卡内容解密以后在用BUID加密----3
            richTextBox1.Text += "\n";
            //====================== write Datas ========================
#if false
            byte[] byteBcrc = new byte[112];
            byteBcrc = Form1.ToDigitsBytes(strbwrite);
            unsafe
            {
                creat_CRC(byteBcrc);
            }
            strbwrite = Form1.ToHexString(byteBcrc);
            richTextBox1.Text += strbwrite;
            richTextBox1.Text += "\n";
#endif// 上面有问题 前面13个不参加CRC
#if false
            byte[] byteBcrc = new byte[112-13];
            byteBcrc = Form1.ToDigitsBytes(strbwrite.Substring(13*2,112*2-13*2));
            unsafe
            {
                creat_CRC(byteBcrc);
            }
            strbwrite = strbwrite.Substring(0,13*2);
            strbwrite += Form1.ToHexString(byteBcrc);
            richTextBox1.Text += strbwrite;
            richTextBox1.Text += "\n";
#endif
            byte block = 0;
            byte[] bytesblock_one = new byte[4];
            for (block = 0; block < 28; block++)//一共28个数据块 全部读出
            {
                bytesblock_one = Form1.ToDigitsBytes(strbwrite.Substring(2*4*block, 2*4));
                status = I15693_Write(g_hDevice, 0x02, Form1.ToDigitsBytes(textBox2.Text), block, bytesblock_one);
                if (status != 0)
                {
                    MessageBox.Show("写失败 !", "error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }

            }
            //成功
            Sys_SetBuzzer(g_hDevice, 20);
        }
    }
}
